package com.bstek.uflo.designer.security.command;

import java.util.List;

import org.hibernate.Session;
import org.springframework.util.Assert;

import com.bstek.uflo.command.Command;
import com.bstek.uflo.designer.security.model.NodeAttribute;
import com.bstek.uflo.designer.security.model.NodeEntry;
import com.bstek.uflo.designer.security.model.ProcessAttribute;
import com.bstek.uflo.designer.security.model.ProcessEntry;
import com.bstek.uflo.designer.security.model.ProcessEntryAssignee;
import com.bstek.uflo.env.Context;

/**
 * @author matt.yao@bstek.com
 * @since 1.0
 */
public class DeleteProcessEntryCascadedCommand implements Command<ProcessEntry> {

	private String processEntryId;

	public DeleteProcessEntryCascadedCommand(String processEntryId) {
		Assert.notNull(processEntryId);
		this.processEntryId = processEntryId;
	}

	public ProcessEntry execute(Context context) {
		Session session = context.getSession();
		this.deleteProcessAttribute(session, processEntryId);
		this.deleteProcessEntryAssignee(session, processEntryId);
		List<NodeEntry> list = this.findNodeEntry(session, processEntryId);
		for (NodeEntry nodeEntry : list) {
			this.deleteNodeEntry(session, nodeEntry);
		}
		this.deleteProcessEntry(session, processEntryId);
		return null;
	}

	private void deleteProcessAttribute(Session session, String processEntryId) {
		String hql = "delete from " + ProcessAttribute.class.getName() + " a where a.processEntryId=:id";
		session.createQuery(hql).setString("id", processEntryId).executeUpdate();
	}

	private void deleteProcessEntryAssignee(Session session, String processEntryId) {
		String hql = "delete from " + ProcessEntryAssignee.class.getName() + " a where a.processEntryId=:id";
		session.createQuery(hql).setString("id", processEntryId).executeUpdate();
	}

	@SuppressWarnings("unchecked")
	private List<NodeEntry> findNodeEntry(Session session, String processEntryId) {
		String hql = "from " + NodeEntry.class.getName() + " e where e.processEntryId=:id";
		return (List<NodeEntry>) session.createQuery(hql).setString("id", processEntryId).list();
	}

	private void deleteNodeEntry(Session session, NodeEntry nodeEntry) {
		String hql = "delete from " + NodeAttribute.class.getName() + " a where a.nodeEntryId=:id";
		session.createQuery(hql).setString("id", nodeEntry.getId()).executeUpdate();
		session.delete(nodeEntry);
	}

	private void deleteProcessEntry(Session session, String processEntryId) {
		String hql = "delete from " + ProcessEntry.class.getName() + " e where e.id=:id";
		session.createQuery(hql).setString("id", processEntryId).executeUpdate();
	}

}
